package gloader

import (
	"strconv"
	"strings"
	"sync"
	"wzgames/internal/constant"
	"wzgames/internal/model/agentp"
	"wzgames/internal/model/mcomm"
	"wzgames/internal/response"
	"wzgames/internal/secure"
	"wzgames/pkg/utils/byteutil"
	"wzgames/pkg/utils/stringutil"
)

// 接入商基本信息

type GAgent struct {
	mu sync.RWMutex

	agent    *agentp.Agent
	agtIdStr string

	ipBlock     bool
	whiteIPList []string
}

func NewAgent(agt *agentp.Agent) *GAgent {
	r := &GAgent{}
	r.SetAgent(agt)
	return r
}

func (a *GAgent) parseWhiteIPs(s string) {
	ipListStr := stringutil.Trim(s, "")
	if ipListStr == constant.AllStr {
		a.ipBlock = false
		return
	}
	a.ipBlock = true
	a.whiteIPList = a.whiteIPList[0:0]
	arr := strings.Split(s, constant.Comma)
	for _, item := range arr {
		wip := stringutil.Trim(item, "")
		a.whiteIPList = append(a.whiteIPList, wip)
	}
}

func (a *GAgent) SetAgent(agt *agentp.Agent) {
	a.mu.Lock()
	a.agent = agt
	a.agtIdStr = strconv.FormatInt(a.agent.AgtID, 10)
	a.parseWhiteIPs(agt.WhiteIP)
	a.mu.Unlock()
}

func (a *GAgent) Available() bool {
	if a.agent == nil {
		return false
	}

	return a.agent.GetStatus() == mcomm.Status_Up
}

// CheckSign sign校验
func (a *GAgent) CheckSign(txt, hashval string) bool {
	md5 := secure.Md5Hex(byteutil.StringToSliceByte(txt + a.agent.GetASect()))
	if md5 == strings.ToLower(hashval) {
		return true
	}
	return false
}

func (a *GAgent) AgtId() int64 {
	return a.agent.GetAgtID()
}

func (a *GAgent) AgtKey() string {
	return a.agent.GetAgtKey()
}

func (a *GAgent) UnameForKey() bool {
	return a.agent.GetUnameForKey()
}

// NameWithPrefix 附上接入商ID
func (a *GAgent) NameWithPrefix(v string) string {
	var bd strings.Builder
	bd.WriteString(a.agtIdStr)
	bd.WriteString(constant.Colon)
	bd.WriteString(v)
	return bd.String()
}

func (a *GAgent) UniquePlayerKey(agtUid, agtUname string) string {
	if a.agent.GetUnameForKey() { // 是否用B端的用户名做唯一处理
		return a.NameWithPrefix(agtUname)
	}

	return a.NameWithPrefix(agtUid) // 用B端用户ID做唯一处理
}

func (a *GAgent) WalletType() mcomm.WalletType {
	return a.agent.GetWalletType()
}

func (a *GAgent) GetCurrency(curr string) *mcomm.SysCurrency {
	if a.agent.CurrList == nil {
		return nil
	}
	a.mu.RLock()
	_, ok := a.agent.CurrList[curr]
	a.mu.RUnlock()
	if !ok {
		return nil
	}

	return CommMgr().GetCurrency(curr)
}

// CheckInstAndCurrency 检查游戏实例对应的币种方案
func (a *GAgent) CheckInstAndCurrency(instId int64, curr string) (int64, int32, int32, int16) {
	sysCurr := a.GetCurrency(curr)
	if sysCurr == nil {
		return 0, 0, 0, response.ErrCurrency
	}
	if a.agent.Games == nil {
		return 0, 0, 0, response.ErrUnAvailable
	}
	a.mu.RLock()
	inst, ok := a.agent.Games[instId]
	a.mu.RUnlock()
	if !ok || inst.Status != mcomm.Status_Up {
		return 0, 0, 0, response.ErrUnAvailable
	}
	if inst.Conf != nil && inst.Conf.Curr2GcID != nil {
		a.mu.RLock()
		gcId, ok1 := inst.Conf.Curr2GcID[sysCurr.CurrID]
		a.mu.RUnlock()
		if ok1 {
			return gcId, sysCurr.CurrID, sysCurr.Precision, 0
		}
	}

	return 0, sysCurr.CurrID, sysCurr.Precision, 0
}

func (a *GAgent) BackIpCheck(bServIP string) bool {
	if !a.ipBlock {
		return true
	}
	for _, item := range a.whiteIPList {
		if item == bServIP {
			return true
		}
	}

	return false
}
